﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MvvmFoundation.Wpf;
using System.Windows;
using System.Windows.Input;
using Revis.VClinicNet.App.External.Server;
using Revis.VClinicNet.App.External.Infrastructure;
using System.Collections.ObjectModel;
using System.Windows.Threading;
using Revis.VClinicNet.App.External.Server.Infrastructure;

namespace Revis.VClinicNet.UI.External.Server.ViewModel
{
    public class MainWindowViewModel : ObservableObject
    {
        private VClinicServer _server = null;

        public MainWindowViewModel()
        {
            _server = new VClinicServer();
            _server.OnStartedServer += new EventHandler(OnStartedServer);
            _server.OnStartingServer += new EventHandler(OnStartingServer);
            _server.OnCreatingCertificate += new EventHandler(OnCreatingCertificate);
            _server.OnOpeningHost += new EventHandler(OnOpeningHost);
            _server.OnClosingServer += new EventHandler(OnClosingServer);
            _server.OnClosedServer += new EventHandler(OnClosedServer);
            _server.LoggerHandler = new EventHandler<ServerLoggerEventArgs>(OnNewLogMessage);
        }

        #region Bindings

        private string _status = String.Empty;
        public string Status
        {
            get { return _status; }
            set
            {
                _status = value;
                RaisePropertyChanged("Status");
            }
        }

        private bool _isDuringWork = false;
        public bool IsDuringWork
        {
            get { return !_isDuringWork; }
            set
            {
                _isDuringWork = value;
                if (_isDuringWork == true) {
                    ShowProgressBar = Visibility.Visible;
                } else {
                    ShowProgressBar = Visibility.Hidden;
                }
                RaisePropertyChanged("IsDuringWork");
            }
        }

        private RelayCommand _startServerCommand = null;
        public ICommand StartServerCommand
        {
            get
            {
                if (_startServerCommand == null) {
                    _startServerCommand = new RelayCommand(StartServer);
                }
                return _startServerCommand;
            }
        }

        private RelayCommand _stopServerCommand = null;
        public ICommand StopServerCommand
        {
            get
            {
                if (_stopServerCommand == null) {
                    _stopServerCommand = new RelayCommand(StopServer);
                }
                return _stopServerCommand;
            }
        }

        private RelayCommand _resetLoggingState = null;
        public ICommand ResetLoggingState
        {
            get
            {
                if (_resetLoggingState == null) {
                    _resetLoggingState = new RelayCommand(ResetLogginState);
                }
                return _resetLoggingState;
            }
        }


        private Visibility _showProgressBar = Visibility.Hidden;
        public Visibility ShowProgressBar
        {
            get { return _showProgressBar; }
            set
            {
                _showProgressBar = value;
                RaisePropertyChanged("ShowProgressBar");
            }
        }

        private ObservableCollection<LogMessage> _loggedMessages = null;
        public ObservableCollection<LogMessage> LoggedMessages
        {
            get
            {
                if (_loggedMessages == null) {
                    _loggedMessages = new ObservableCollection<LogMessage>();
                }
                return _loggedMessages;
            }
            set
            {
                _loggedMessages = value;
                RaisePropertyChanged("LoggedMessages");
            }
        }

        #endregion

        #region Privates

        private void StartServer()
        {
            _server.StartAsync();
        }

        private void StopServer()
        {
            _server.CloseAsync();
        }

        private void ResetLogginState()
        {
            LoggedMessages.Clear();
        }

        private void OnStartedServer(object sender, EventArgs args)
        {
            IsDuringWork = false;
            Status = "Serwer uruchomiony";
            AddServerLogMessage("StartedServer");
        }

        private void OnStartingServer(object sender, EventArgs args)
        {
            IsDuringWork = true;
            Status = "Uruchamianie serwera";
            AddServerLogMessage("StartServer");
        }

        private void OnCreatingCertificate(object sender, EventArgs args)
        {
            Status = "Tworzenie certyfikatu";
            AddServerLogMessage("CreateCertificate");
        }

        private void OnOpeningHost(object sender, EventArgs args)
        {
            Status = "Otwieranie połączenia";
            AddServerLogMessage("OpenHost");
        }

        private void OnClosingServer(object sender, EventArgs args)
        {
            IsDuringWork = true;
            Status = "Zamykanie serwera";
            AddServerLogMessage("CloseServer");
        }

        private void OnClosedServer(object sender, EventArgs args)
        {
            IsDuringWork = false;
            Status = "Serwer zatrzymany";
            AddServerLogMessage("ClosedServer");
        }

        private void OnNewLogMessage(object sender, ServerLoggerEventArgs args)
        {
            AddNewLogMessage(args.Message);
        }

        private void AddNewLogMessage(LogMessage msg)
        {
            Application.Current.Dispatcher.Invoke(new Action(() => {
                LoggedMessages.Add(msg);
            }), null);
        }

        private void AddServerLogMessage(string cmd)
        {
            AddNewLogMessage(new LogMessage("Srv/#", cmd));
        }

        #endregion
    }
}
